{
  class ClassWithPrivateField {
    // 公有属性
    instanceField;
    instanceFieldWithInitializer = "实例字段";
    static staticField;
    static staticFieldWithInitializer = "静态字段";

    // 声明私有属性
    // 在构造函数调用之前添加，或者在构造函数调用 super() 之后立即添加
    #privateField;
    static #privateStaticField = 42;

    constructor() {
      this.#privateField = 42;
    }

    static publicStaticMethod() {
      return ClassWithPrivateField.#privateStaticField;
    }
  }

  class SubClass extends ClassWithPrivateField {
    #subPrivateField;

    constructor() {
      super();
      this.#subPrivateField = 23;
    }
  }

  const sub = new SubClass();
  // - #subPrivateField 是 SubClass 的私有属性，外部无法访问
  // - #privateField 是基类 ClassWithPrivateField 的私有属性，派生类 SubClass 无法访问
  console.log(sub);
  console.log(ClassWithPrivateField.publicStaticMethod());
  console.dir(ClassWithPrivateField);
  console.dir(ClassWithPrivateField.prototype);
}

{
  class AnimalClass {
    name;
    constructor(name) {
      this.name = name;
    }
    sayHi() {
      console.log(`hi, my name is ${this.name}`);
    }
    static sayHi() {
      console.log("hi");
    }
  }

  function AnimalFn(name) {
    this.name = name;
  }
  AnimalFn.prototype.sayHi = function () {
    console.log(`hi, my name is ${this.name}`);
  };
  AnimalFn.sayHi = function () {
    console.log("hi");
  };

  console.log("--- class ---");
  AnimalClass.sayHi();
  const animalClass = new AnimalClass();
  for (const k in animalClass) {
    console.log(k);
  }

  console.log("--- function ---");
  const animalFn = new AnimalFn();
  for (const k in animalFn) {
    console.log(k);
  }
}

{
  class Animal {
    // 字段
    // 公有字段
    username;
    //  私有字段
    #gender;
    // 公有静态字段
    static staticName = "static-name";
    // 私有静态字段
    static #staticGender = "unknow";
    constructor({ username, age, gender }) {
      this.username = username;
      this.age = age;
      this.#gender = gender;
    }

    get gender() {
      return this.#gender;
    }

    set setAge(value) {
      this.age = value;
    }

    // 方法
    method() {
      console.log("方法");
    }

    #privateMethod() {
      console.log("私有方法");
    }

    static staticMethod() {
      console.log("静态方法");
    }

    static #staticPrivateMethod() {
      console.log("静态私有方法");
    }
  }

  const animal = new Animal({ username: "tom", age: 20, gender: "male" });
  console.log(animal.username); // tom
  console.log(animal.age); // 20
  console.log(animal.gender); // male

  animal.method(); // 方法
  Animal.staticMethod(); // 静态方法
}

{
  class Animal extends null {
    constructor() {
      // super(); // TypeError: super() is not allowed in a null context
      return Object.create(null);
    }
  }

  const animal = new Animal();
  console.log(animal instanceof Animal); // false
  console.log(Object.getPrototypeOf(animal)); // null
}

{
  class Animal {
    name = "animal";

    constructor() {
      console.log(this.name);
    }
  }

  class Rabbit extends Animal {
    name = "rabbit";
  }

  new Animal(); // animal
  new Rabbit(); // animal
}
